#include <thread>

#include "logger/logger.hpp"
#include "clocker/clocker.h"
#include "./smart/smart_mpp_decoder.hpp"
#include "./smart/h264_file_nalu_pars.h"

int main(const int argc, const char* argv[])
{
    if (argc != 2) {
        printf("./tst_decode_h264 [filename.h264]\n");
        exit(EXIT_FAILURE);
    } else {
        printf("> %s %s\n", argv[0], argv[1]);
    }
    SmartMppDecoder mpp_dec(MPP_VIDEO_CodingAVC);
    H264FileNaluPars h264_nalu;
    FILE* decoded_fd;

    decoded_fd = fopen("test.yuv", "wb");
    if (decoded_fd == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    h264_nalu.init(argv[1], H264FileNaluPars::FMT_H264);

    /* 开启线程取帧并作处理 */
    std::thread thread_get_frame([&mpp_dec, &h264_nalu]{
        while (true) {
            getchar();
            std::vector<uint8_t> buff = h264_nalu.get_nalu_frame();
            if (buff.size() <= 0) {
                log_debug("> file open end.");
                mpp_dec.stop();
                return;
            }
            while (buff.size() < 100) {
                std::vector<uint8_t> tmp_data = h264_nalu.get_nalu_frame();
                if (tmp_data.size() == 0) {
                    printf("End of file reading.\n");
                    continue;
                }
                buff.insert(buff.end(), tmp_data.begin(), tmp_data.end());
            }
            log_debug("<--- dec_put_buf: size %d.", buff.size());
            clocker_begin();
            printf("\n--- buff.size():%d ---\n", buff.size());
            mpp_dec.put_packet(buff.data(), buff.size());
        }
    });

    /* 获取码流并给硬件进行解码 */
    log_debug("start get_frame.");
#if 1
    mpp_dec.loop_get_frame([&decoded_fd](std::vector<uint8_t>& data){
        clocker_end();
        // fwrite(data.data(), data.size(), 1, decoded_fd);
        log_debug("-------------------------------------------------> get frame len:[%d].\n", data.size());
    });
#else
    mpp_dec.loop_get_frame([&decoded_fd](uint8_t* buf, uint32_t len){
        // clocker_end();
        fwrite(buf, len, 1, decoded_fd);
        log_debug("-------------------------------------------------> get frame len:[%d].\n", len);
    });
#endif

    log_debug("--------- end ---------");
    fclose(decoded_fd);
    thread_get_frame.join();
    mpp_dec.deinit();
    h264_nalu.deinit();
}